﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace production
{
    public static class SysLibs
    {
        public static string ValidateString(string str)
        {
            return (str == null ? "N/A" : str);
        }
    }
    public static class ProductionLibs
    {
        public static string GetProdTaskCode(string itemCode)
        {
            return null;
        }

        public static decimal GetPlanPrice(string itemCode)
        {
            return 1;
        }
    }
    
    public static class Settings
    {
        public static byte sysPrecisionAmt = common.SysLibs.GetPrecisionFromMask(CommonTypes.Settings.sysMaskLocalAmt);
        public static byte sysPrecisionQty = common.SysLibs.GetPrecisionFromMask(CommonTypes.Settings.sysMaskQty);
        public static byte sysPrecisionRatio = common.SysLibs.GetPrecisionFromMask(CommonTypes.Settings.sysMaskDecimal);
        public static byte sysPrecisionPrice = sysPrecisionAmt; //common.SysLibs.GetPrecisionFromMask(CommonTypes.Settings.sysMaskDecimal);
        public static byte sysPrecisionPerc = 2; //common.SysLibs.GetPrecisionFromMask(CommonTypes.Settings.sysMaskPercent);
    }
    public static class DataLibs
    {
        public static void InitData(tempDS.productionPlanRow row)
        {
            row.itemCode = "";
            row.taskCode = "";
            row.planQty = 0;
            row.produceQty = 0;
        }
        public static void InitData(tempDS.productionRatioMaterialRow row)
        {
            row.productCode = "";
            row.taskCode = "";
            row.itemCode = "";
            row.planQty = 0;
            row.planRatio = 0;
            row.productionQty = 0;
            row.productionRatio = 0;
            row.ratioVariantPerc = 0;
            row.productionAmt = 0;
            row.completeQty = 0;
            row.completeAmt = 0;
        }
        public static void InitData(tempDS.productionRatioExpenseRow row)
        {
            row.productCode = "";
            row.taskCode = "";
            row.accountNo = "";
            row.planAmt = 0;
            row.productionAmt = 0;
            row.planRatio = 0;
            row.productionRatio = 0;
            row.ratioVariantPerc = 0;
            row.completeAmt = 0;
        }
        public static void InitData(tempDS.productionDataRow row)
        {
            row.productCode = "";
            row.taskCode = "";
            row.planQty = 0;
            row.produceQty = 0;
            row.produceMaterialAmt = 0;
            row.produceExpenseAmt = 0;
            row.completePerc = 0;
            row.distProduceQty = 0;
            row.distProduceAmt = 0;
        }
        public static void InitData(tempDS.inventoryRow row)
        {
            row.accountNo = "";
            row.houseCode = "";
            row.itemCode = "";
            row.qty = 0;
            row.amt = 0;
        }
        public static void InitData(tempDS.materialRow row)
        {
            row.itemCode = "";
            row.toProductCode = "";
            row.toTaskCode = "";
            row.qty = 0;
            row.amt = 0;
            row.completeQty = 0;
            row.completeAmt = 0;
            row.differentialAmt = 0;
            row.completePerc = 0;
        }
        public static void InitData(tempDS.expenseRow row)
        {
            row.accountNo = "";
            row.toProductCode = "";
            row.toTaskCode = "";
            row.amt = 0;
            row.completeAmt = 0;
            row.completePerc = 0;
        }
        public static void InitData(tempDS.accountimgRow row)
        {
            row.companyCode = "";
            row.voucherId = "";
            row.accountNo = "";
            row.dAccountNo = "";
            row.deAmt = 0;
            row.crAmt = 0;
        }
        public static void InitData(tempDS.errorRow row)
        {
            row.code = "";
            row.type = "";
            row.description = "";
            row.info = "";
            row.id = 0;
        }

        public static tempDS.productionRatioMaterialRow AddRow_ProdMaterialRatio(string productCode, string taskCode, string itemCode, tempDS.productionRatioMaterialDataTable dataTbl)
        {
            tempDS.productionRatioMaterialRow dataRow = dataTbl.FindByproductCodeitemCodetaskCode(productCode, itemCode, taskCode);
            if (dataRow == null)
            {
                dataRow = dataTbl.NewproductionRatioMaterialRow();
                DataLibs.InitData(dataRow);
                dataRow.productCode = productCode;
                dataRow.taskCode = taskCode;
                dataRow.itemCode = itemCode;
                dataTbl.AddproductionRatioMaterialRow(dataRow);
            }
            return dataRow;
        }
        public static tempDS.productionRatioExpenseRow AddRow_ProdExpenseRatio(string productCode, string taskCode, string accountNo, tempDS.productionRatioExpenseDataTable dataTbl)
        {
            tempDS.productionRatioExpenseRow dataRow = dataTbl.FindByproductCodeaccountNotaskCode(productCode, accountNo, taskCode);
            if (dataRow == null)
            {
                dataRow = dataTbl.NewproductionRatioExpenseRow();
                DataLibs.InitData(dataRow);
                dataRow.productCode = productCode;
                dataRow.taskCode = taskCode;
                dataRow.accountNo = accountNo;
                dataTbl.AddproductionRatioExpenseRow(dataRow);
            }
            return dataRow;
        }
        
        public static tempDS.productionPlanRow AddRow_ProductionPlan(string productCode, string taskCode, tempDS.productionPlanDataTable dataTbl)
        {
            tempDS.productionPlanRow dataRow = dataTbl.FindBytaskCodeitemCode(taskCode, productCode);
            dataRow = dataTbl.FindBytaskCodeitemCode(taskCode, productCode);
            if (dataRow == null)
            {
                dataRow = dataTbl.NewproductionPlanRow();
                production.DataLibs.InitData(dataRow);
                dataRow.itemCode = productCode;
                dataRow.taskCode = taskCode;
                dataTbl.AddproductionPlanRow(dataRow);
            }
            return dataRow;
        }
        public static tempDS.productionDataRow AddRow_ProductionData(string productCode, string taskCode, tempDS.productionDataDataTable dataTbl)
        {
            tempDS.productionDataRow dataRow;
            dataRow = dataTbl.FindBytaskCodeproductCode(taskCode, productCode);
            if (dataRow==null)
            {
                dataRow = dataTbl.NewproductionDataRow();
                DataLibs.InitData(dataRow);
                dataRow.taskCode = taskCode;
                dataRow.productCode = productCode;
                dataTbl.AddproductionDataRow(dataRow);
            }
            return dataRow;
        }

        public static tempDS.materialRow Add_Material(string itemCode,string toProductCode,string toTaskCode, tempDS.materialDataTable dataTbl)
        {
            toProductCode = (toProductCode==null ? "" : toProductCode);
            toTaskCode = (toTaskCode == null ? "" : toTaskCode);
            tempDS.materialRow materialRow = dataTbl.FindBytoTaskCodetoProductCodeitemCode(toTaskCode,toProductCode,itemCode);
            if (materialRow == null)
            {
                materialRow = dataTbl.NewmaterialRow();
                production.DataLibs.InitData(materialRow);
                materialRow.itemCode = itemCode;
                materialRow.toProductCode = toProductCode;
                materialRow.toTaskCode = toTaskCode;
                dataTbl.AddmaterialRow(materialRow);
            }
            return materialRow;
        }
        public static tempDS.expenseRow Add_Expense(string accountNo,string toProductCode,string toTaskCode, tempDS.expenseDataTable dataTbl)
        {
            toProductCode = (toProductCode == null ? "" : toProductCode);
            toTaskCode = (toTaskCode == null ? "" : toTaskCode);
            tempDS.expenseRow expenseRow = dataTbl.FindByaccountNotoTaskCodetoProductCode(accountNo,toTaskCode,toProductCode);
            if (expenseRow == null)
            {
                expenseRow = dataTbl.NewexpenseRow();
                production.DataLibs.InitData(expenseRow);
                expenseRow.accountNo = accountNo;
                dataTbl.AddexpenseRow(expenseRow);
            }
            return expenseRow;
        }

        public static tempDS.errorRow AddRow_Error(string code, tempDS.errorDataTable dataTbl)
        {
            tempDS.errorRow dataRow;
            dataRow = dataTbl.NewerrorRow();
            DataLibs.InitData(dataRow);
            dataRow.code = code;
            dataTbl.AdderrorRow(dataRow);
            return dataRow;
        }
    }

    public class ProductionErrors : tempDS.errorDataTable
    {
        public enum Codes : byte
        {
            None = 0,
            Info = 1,
            ProdTaskCircular = 2,
            ProductTaskNotExisted = 3,
            NotInProductPlan = 4,
            ProductPlanQtyInvalid = 5,
            DistributionFailed = 6,
            NotInProductTemplate = 7,
            NoProductPlanPrice = 8,
            IncompleteAdjustFailed = 9,
            InventoryNotAvailable = 10,
            InventoryInvalid = 11
        };
        public ProductionErrors()
        {
            this.DefaultView.Sort = this.codeColumn.ColumnName; 
        }

        private int mySerial = 0; 
        public new void Clear()
        {
            base.Clear();
            this.mySerial = 0;
        }
        public void Add(Codes code)
        {
            string key = ((byte)code).ToString();
            Add(key, code.ToString(), GetText(code), "");
        }
        public void Add_TaskItem(Codes code, string taskCode, string itemCode)
        {
            string key = ((byte)code).ToString() + "-T-" + SysLibs.ValidateString(taskCode) + "-I-" + SysLibs.ValidateString(itemCode);
            string info = "Task=" + SysLibs.ValidateString(taskCode) + ",Item=" + SysLibs.ValidateString(itemCode);
            Add(key, code.ToString(), GetText(code), info);
        }
        public void Add_Item(Codes code, string itemCode)
        {
            string key = ((byte)code).ToString() + "-I-" + SysLibs.ValidateString(itemCode);
            string info = "Item=" + SysLibs.ValidateString(itemCode);
            Add(key, code.ToString(), GetText(code), info);
        }
        public void Add_Account(Codes code, string accountNo)
        {
            string key = ((byte)code).ToString() + "-A-" + SysLibs.ValidateString(accountNo);
            string info = "Account=" + SysLibs.ValidateString(accountNo);
            Add(key, code.ToString(), GetText(code), info);
        }

        public void Add_Text(string desc,string info)
        {
            Add("T" + (this.mySerial + 1).ToString(),Codes.Info.ToString(), desc, info);
        }
        public void Add(string code, string type, string description, string info)
        {
            if (this.DefaultView.FindRows(code).Length > 0) return; 
            tempDS.errorRow errorRow = DataLibs.AddRow_Error(code, this);
            errorRow.type = type;
            errorRow.description = description;
            errorRow.info = info;
            errorRow.id = ++this.mySerial;
        }

        private void Insert(tempDS.errorRow row)
        {
            tempDS.errorRow newRow;
            newRow = DataLibs.AddRow_Error(row.code, this);
            newRow.id = ++this.mySerial;
            newRow.code = row.code;
            newRow.type = row.type;
            newRow.description = row.description;
            newRow.info = row.info;
        }
        public void Merge(ProductionErrors errors)
        {
            for (int idx = 0; idx < errors.Count(); idx++)
            {
                if (this.DefaultView.FindRows(errors[idx].code).Length > 0) continue;
                this.Insert(errors[idx]);
            }
        }
        public void Append(ProductionErrors errors)
        {
            for (int idx = 0; idx < errors.Count(); idx++)
            {
                this.Insert(errors[idx]);
            }
        }
        

        public static string GetText(Codes code)
        {
            switch (code)
            {
                case ProductionErrors.Codes.ProdTaskCircular: return "Công đọan sản xuất bị lặp vòng";
                case ProductionErrors.Codes.ProductTaskNotExisted: return "Công đọan sản xuất không tồn tại";
                case ProductionErrors.Codes.NotInProductPlan: return "Không có trong kế họach sản xuất";
                case ProductionErrors.Codes.ProductPlanQtyInvalid: return "Số lượng (kế hoach sản xuất) không hợp lệ";
                case ProductionErrors.Codes.DistributionFailed: return "Phân bổ gặp lỗi";
                case ProductionErrors.Codes.NotInProductTemplate: return "Không có trong định mức sản xuất";
                case ProductionErrors.Codes.NoProductPlanPrice: return "Vật tư chưa có giá kế họah";
                case ProductionErrors.Codes.IncompleteAdjustFailed: return "Điều chỉnh dở dang gặp lỗi (hệ thống)";
                case ProductionErrors.Codes.InventoryNotAvailable: return "Không có tồn kho";
                case ProductionErrors.Codes.InventoryInvalid: return "Tồn kho không hợp lệ";
                case ProductionErrors.Codes.Info: return "Thông tin";
            }
            return code.ToString();
        }
        public override string ToString()
        {
            string retVal = "";
            for (int idx = 0; idx < this.Count; idx++)
            {
                retVal += (retVal == "" ? "" : common.Consts.constCRLF) + this[idx].type + "," + this[idx].description + "," + this[idx].info;
            }
            return retVal;
        }
    }
    
    public class Progress
    {
        public class EventArgs
        {
            public string Text = "";
            public int MaxValue = 0;
        }
        public class ChangedEventArgs
        {
            public bool Cancelled = false;
        }
    }
}
